﻿var Suucha = Suucha || {};

Suucha.ExpressionType = {};
Suucha.ExpressionType.Member = 0;
Suucha.ExpressionType.Constant = Suucha.ExpressionType.Member + 1;
Suucha.ExpressionType.And = Suucha.ExpressionType.Member + 2;
Suucha.ExpressionType.Equal = Suucha.ExpressionType.Member + 3;
Suucha.ExpressionType.GreaterThan = Suucha.ExpressionType.Member + 4;
Suucha.ExpressionType.GreaterThanOrEqual = Suucha.ExpressionType.Member + 5;
Suucha.ExpressionType.LessThan = Suucha.ExpressionType.Member + 6;
Suucha.ExpressionType.LessThanOrEqual = Suucha.ExpressionType.Member + 7;
Suucha.ExpressionType.NotEqual = Suucha.ExpressionType.Member + 8;
Suucha.ExpressionType.Or = Suucha.ExpressionType.Member + 9;
Suucha.ExpressionType.Like = Suucha.ExpressionType.Member + 10;
Suucha.ExpressionType.NotLike = Suucha.ExpressionType.Member + 11;
Suucha.ExpressionType.In = Suucha.ExpressionType.Member + 12;
Suucha.ExpressionType.InLike = Suucha.ExpressionType.Member + 13;

Suucha.Expression = function () {
    this.NodeType = -1;
}

Suucha.BinaryExpression = function (json) {
    Suucha.Expression.call(this);
    this.Left = null;
    this.Right = null;

    if (json) {
        this.NodeType = json.NodeType;
        if (json.Left) {
            this.Left = Suucha.Expression.FromJson(json.Left);
        }
        if (json.Right) {
            this.Right = Suucha.Expression.FromJson(json.Right);
        }
    }
}

Suucha.BinaryExpression.prototype = new Suucha.Expression();


Suucha.MemberExpression = function (json) {
    Suucha.Expression.call(this);
    this.Name = "";
    this.NodeType = Suucha.ExpressionType.Member;
    if (json) {
        if (typeof json == "string") {
            this.Name = json;
        }
        else {
            this.Name = json.Name;
        }
    }
}
Suucha.MemberExpression.prototype = new Suucha.Expression();

Suucha.ConstantExpression = function (json) {
    Suucha.Expression.call(this);
    this.Value;
    this.NodeType = Suucha.ExpressionType.Constant;
    if (json) {
        var type = typeof json;
        if (type == 'string' || type == 'number' || type == 'boolean') {
            this.Value = json;
        }
        else {
            this.Value = json.Value;
        }
    }
}
Suucha.ConstantExpression.prototype = new Suucha.Expression();

Suucha.Expression.Member = function (name) {
    var me = new Suucha.MemberExpression();
    me.Name = name;
    return me;
}

Suucha.Expression.Constant = function (value) {
    var ce = new Suucha.ConstantExpression();
    ce.Value = value;
    return ce;
}

Suucha.Expression.In = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.In;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.InLike = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.InLike;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.And = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.And;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.Equal = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.Equal;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.GreaterThan = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.GreaterThan;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.GreaterThanOrEqual = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.GreaterThanOrEqual;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.LessThan = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.LessThan;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.LessThanOrEqual = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.LessThanOrEqual;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.NotEqual = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.NotEqual;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.Or = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.Or;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.Like = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.Like;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.NotLike = function (left, right) {
    if (typeof left == 'string') {
        left = Suucha.Expression.Member(left);
    }
    var typeofRight = typeof right;
    if (typeofRight == 'string' || typeofRight == 'number' || typeofRight == 'boolean') {
        right = Suucha.Expression.Constant(right);
    }
    var be = new Suucha.BinaryExpression();
    be.NodeType = Suucha.ExpressionType.NotLike;
    be.Left = left;
    be.Right = right;
    return be;
}

Suucha.Expression.FromJson = function (json) {
    var exp;
    switch (json.NodeType) {
        case Suucha.ExpressionType.Member:
            exp = new Suucha.MemberExpression(json);
            break;
        case Suucha.ExpressionType.Constant:
            exp = new Suucha.ConstantExpression(json);
            break;
        default:
            exp = new Suucha.BinaryExpression(json);
            break;
    }
    return exp;
}

Suucha.OrderBy = function (name, asc) {
    this.Member = null;
    this.Asc = true;
    if (asc != undefined) {
        this.Asc = asc;
    }
    if (name) {
        if (typeof name == 'string') {
            this.Member = Suucha.Expression.Member(name);
            return;
        }
        this.Asc = name.Asc;
        if (name.Name) {
            this.Member = Suucha.Expression.Member(name.Name);
            return;
        }
        if (name.Member) {
            this.Member = name.Member;
        }
    }
}
Suucha.OrderBy.OrderBy = function (name) {
    var sorts = new Suucha.OrderBy.Sorts();
    sorts.Add(new Suucha.OrderBy(name, true));
    return sorts;
}
Suucha.OrderBy.OrderByDescending = function (name) {
    var sorts = new Suucha.OrderBy.Sorts();
    sorts.Add(new Suucha.OrderBy(name, false));
    return sorts;
}
Suucha.OrderBy.prototype.ThenBy = function (name) {
    var sorts = new Suucha.OrderBy.Sorts();
    sorts.Add(this);
    sorts.Add(new Suucha.OrderBy(name, true));
    return sorts;
}
Suucha.OrderBy.prototype.ThenByDescending = function (name) {
    var sorts = new Suucha.OrderBy.Sorts();
    sorts.Add(this);
    sorts.Add(new Suucha.OrderBy(name, false));
    return sorts;
}
Suucha.OrderBy.Sorts = function () {
    var all = new Array();
    this.ToArray = function () {
        return all;
    }
    this.Add = function (orderBy) {
        all.push(orderBy);
    }
}
Suucha.OrderBy.Sorts.prototype.ThenBy = function (name) {
    this.Add(new Suucha.OrderBy(name, true));
    return this;
}
Suucha.OrderBy.Sorts.prototype.ThenByDescending = function (name) {
    this.Add(new Suucha.OrderBy(name, false));
    return this;
}

Suucha.SearchParameters = function () {
    this.Sorts = new Array();
    this.Page = 1;
    this.PageSize = 20;
    this.Condition = null;
    this.Selector = '';

}

Suucha.SearchParameters.FromJson = function (json) {
    if (json) {
        var search = new Suucha.SearchParameters();
        if (json.Page) {
            search.Page = json.Page;
        }
        if (json.PageSize) {
            search.PageSize = json.PageSize;
        }
        if (json.Selector) {
            search.Selector = json.Selector;
        }
        if (json.Condition) {
            search.Condition = Suucha.Expression.FromJson(json.Condition);
        }
        if (json.Sorts) {
            for (var sort in json.Sorts) {
                search.Sorts.push(new Suucha.OrderBy(json.Sorts[sort]));
            }
        }
        return search;
    }
    return null;
}